/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-09-10
*/
package com.rzico.order.service;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rzico.account.entity.Refunds;
import com.rzico.account.model.Attach;
import com.rzico.account.service.PointService;
import com.rzico.base.BaseMapper;
import com.rzico.base.impl.BaseServiceImpl;
import com.rzico.basics.entity.Member;
import com.rzico.basics.mapper.MemberMapper;
import com.rzico.core.entity.SysUser;
import com.rzico.core.mapper.SysUserMapper;
import com.rzico.exception.CustomException;
import com.rzico.order.entity.*;
import com.rzico.order.enumx.OrderStatusEnum;
import com.rzico.order.mapper.GroupBuyMapper;
import com.rzico.order.mapper.GroupPeriodMapper;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.rzico.order.mapper.GroupOrderMapper;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * <pre>
 * 团购订单业务类
 * </pre>
 *
 * @author Rzico Boot
 * @version 1.0
 */
@Service
public class GroupOrderService extends BaseServiceImpl<GroupOrder, String> {

    @Autowired
    private GroupOrderMapper groupOrderMapper;

    @Autowired
    private GroupBuyMapper groupBuyMapper;

    @Autowired
    private GroupPeriodMapper groupPeriodMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired @Lazy
    private OrderService orderService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private PointService pointService;

    @Override
    public BaseMapper<GroupOrder, String> getMapper() {
        return groupOrderMapper;
    }

    @Transactional(rollbackFor = Exception.class)
    public int addBuyNum(Long id,Integer value) {

        Map<String, Object> params = new HashMap<>();
        params.put("id",id);
        params.put("value",value);
        groupBuyMapper.addBuyNum(params);

        return 1;
    }

    @Transactional(rollbackFor = Exception.class)
    public int decBuyNum(Long id,Integer value) {
        Map<String, Object> params = new HashMap<>();
        params.put("id",id);
        params.put("value",value);
        Integer w = groupBuyMapper.decBuyNum(params);
        if (w==0) {
            throw new CustomException("更新失败");
        }
        return w;
    }

    public List<GroupOrder> getItemList(Long periodId) {

        Map<String,Object> params = new HashMap<>();
        params.put("periodId",periodId);
        params.put("sortField","id");
        params.put("sortType","desc");
        return groupOrderMapper.selectList(params);

    }


    public List<GroupOrder> getOrderList(Long periodId) {

        Map<String,Object> params = new HashMap<>();
        params.put("periodId",periodId);
        params.put("robot",0);
        params.put("sortField","id");
        params.put("sortType","desc");
        return groupOrderMapper.selectList(params);

    }


    public List<GroupOrder> getItemList(Long groupBuyId,Integer periodNum) {

        Map<String,Object> params = new HashMap<>();
        params.put("groupBuyId",groupBuyId);
        params.put("periodNum",periodNum);
        params.put("sortField","id");
        params.put("sortType","desc");
        List<GroupPeriod> periodList = groupPeriodMapper.selectList(params);
        if (periodList.size()>0) {
            return getItemList(periodList.get(0).getId());
        } else {
            throw new CustomException("无效期号");
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void addOrder(Long orderId) {

        Order order = orderService.selectByPrimaryKey(orderId);

        GroupBuy groupBuy = groupBuyMapper.selectByPrimaryKey(order.getGroupBuyId());
        GroupOrder groupOrder = new GroupOrder();

        if (groupBuy.getStatus().equals(2)) {
            //如果成团，本期结果，订单保留到下一期
            groupOrder.setPeriodId(0L);
        } else {
            groupOrder.setPeriodId(groupBuy.getPeriodId());
        }

        groupOrder.setMemberId(order.getMemberId());
        groupOrder.setCreateDate(new Date());
        groupOrder.setEnterpriseId(order.getEnterpriseId());
        groupOrder.setGroupBuyId(order.getGroupBuyId());
        groupOrder.setOrderId(order.getId());
        groupOrder.setOrderStatus(0);
        groupOrder.setRobot(false);

        groupOrder.setSn(order.getSn());
        groupOrder.setAddress(order.getAddress());
        groupOrder.setPhone(order.getPhone());
        groupOrder.setConsignee(order.getConsignee());
        groupOrder.setReceiverId(order.getReceiverId());
        groupOrder.setAreaId(order.getAreaId());
        groupOrder.setAreaName(order.getAreaName());

        Member member = memberMapper.selectByPrimaryKey(order.getMemberId());

        SysUser sysUser = sysUserMapper.selectByPrimaryKey(member.getUserId());
        groupOrder.setAvatar(sysUser.getAvatar());
        groupOrder.setNickname(sysUser.getNickname());

        groupOrderMapper.insertUseGeneratedKeys(groupOrder);

        //不为0都是本期订单，有效结单
        if (!groupOrder.getPeriodId().equals(0L)) {

            GroupPeriod groupPeriod = groupPeriodMapper.selectByPrimaryKey(groupBuy.getPeriodId());
            groupPeriod.setBuyNum(groupPeriod.getBuyNum()+1);
            addBuyNum(groupBuy.getId(),1);

            if (groupPeriod.getBuyNum() >= groupBuy.getGroupNum()) {

                groupPeriod.setStatus(1);
                groupBuy.setStatus(2);
                groupBuyMapper.updateByPrimaryKeySelective(groupBuy);

                List<GroupOrder> groupOrderList = getOrderList(groupBuy.getPeriodId());

                //开始随机获取中奖者
                Integer g = groupBuy.getOrderNum();
                if (g>groupOrderList.size()) {
                    g = groupOrderList.size();
                }
                List<Integer> rd = new ArrayList<>();
                Random r = new Random();
                while (g > 0) {
                    if (groupOrderList.size() > 1) {
                        int n = r.nextInt(groupOrderList.size());
                        if (rd.indexOf(n) < 0) {
                            rd.add(n);
                            g--;
                        }
                    } else {
                        rd.add(0);
                        g--;
                    }
                    //System.out.println("======= while g>0");
                }

                for (Integer i : rd) {
                    GroupOrder go = groupOrderList.get(i);
                    go.setOrderStatus(1);
                    groupOrderMapper.updateByPrimaryKeySelective(go);

                }

            }

            groupPeriodMapper.updateByPrimaryKeySelective(groupPeriod);
        }

    }



    @Transactional(rollbackFor = Exception.class)
    public void addRobot(Long groupBuyId) {

        GroupBuy groupBuy = groupBuyMapper.selectByPrimaryKey(groupBuyId);

        //已经成团，机器人无效
        if (groupBuy.getStatus().equals(2)) {
            return;
        }

        Map<String,Object> params = new HashMap<>();
        //检查机器人数量
        params.put("periodId",groupBuy.getPeriodId());
        params.put("robot",1);
        Integer w1 =  groupOrderMapper.selectRowCount(params);
        if (w1>=groupBuy.getRobotNum()) {
            return;
        }


        GroupPeriod groupPeriod = groupPeriodMapper.selectByPrimaryKey(groupBuy.getPeriodId());
        List<GroupOrder> histList = getOrderList(groupBuy.getPeriodId());
        if (histList.size()==0) {
            return;
        } else {
            GroupOrder groupOrder = histList.get(0);
            if (groupOrder.getCreateDate().after(DateUtils.addMinutes(new Date(),-10))) {
                return;
            }
        }

        GroupOrder groupOrder = new GroupOrder();

        groupOrder.setMemberId(null);
        groupOrder.setCreateDate(new Date());
        groupOrder.setEnterpriseId(groupBuy.getEnterpriseId());
        groupOrder.setGroupBuyId(groupBuyId);
        groupOrder.setOrderId(null);
        groupOrder.setOrderStatus(0);
        groupOrder.setRobot(true);

        groupOrder.setSn(null);
        groupOrder.setAddress(null);
        groupOrder.setPhone(null);
        groupOrder.setConsignee(null);
        groupOrder.setReceiverId(null);
        groupOrder.setAreaId(null);
        groupOrder.setAreaName(null);
        groupOrder.setPeriodId(groupBuy.getPeriodId());

        PageHelper.startPage(1,100);
        Map<String,Object> usrParams = new HashMap<>();
        usrParams.put("hasAvatar",true);
        List<SysUser> sysUserList = sysUserMapper.selectList(usrParams);

        Random random = new Random();
        int rc = random.nextInt(sysUserList.size());

        SysUser sysUser = sysUserList.get(rc);

        groupOrder.setAvatar(sysUser.getAvatar());
        groupOrder.setNickname(sysUser.getNickname());
        groupOrder.setPhone(sysUser.getMobile());

        groupOrderMapper.insertUseGeneratedKeys(groupOrder);

        groupPeriod.setBuyNum(groupPeriod.getBuyNum()+1);
        addBuyNum(groupBuyId,1);

        if (groupPeriod.getBuyNum()>=groupBuy.getGroupNum()) {
            groupPeriod.setStatus(1);
            groupBuy.setStatus(2);
            groupBuyMapper.updateByPrimaryKeySelective(groupBuy);

            List<GroupOrder> groupOrderList = getOrderList(groupBuy.getPeriodId());

            //开始随机获取中奖者
            Integer g = groupBuy.getOrderNum();
            if (g>groupOrderList.size()) {
                g = groupOrderList.size();
            }
            List<Integer> rd = new ArrayList<>();
            Random r = new Random();
            while (g>0) {
                if (groupOrderList.size()>1) {
                    int n = r.nextInt(groupOrderList.size());
                    if (rd.indexOf(n) < 0) {
                        rd.add(n);
                        g--;
                    }
                } else {
                    rd.add(0);
                    g--;
                }
                //System.out.println("======= robot g>0");
            }

            for (Integer i:rd) {
                GroupOrder go = groupOrderList.get(i);
                go.setOrderStatus(1);
                groupOrderMapper.updateByPrimaryKeySelective(go);

            }

        }

        groupPeriodMapper.updateByPrimaryKeySelective(groupPeriod);

    }

    @Transactional(rollbackFor = Exception.class)
    public List<Refunds> newPeriod(Long groupBuyId,String sn) {

        GroupBuy groupBuy = groupBuyMapper.selectByPrimaryKey(groupBuyId);
        List<GroupOrder> groupOrderList = getOrderList(groupBuy.getPeriodId());
        List<Refunds> refundsList = new ArrayList<>();

        //开始处理订单
        Integer w = 0;
        for (GroupOrder groupOrder:groupOrderList) {

            Order order = orderService.findById(groupOrder.getOrderId());
            if (groupOrder.getOrderStatus().equals(1)) {

                //团中者
                order.setOrderStatus(OrderStatusEnum.ORDER_STATUS_CONFIRM.getId());
                orderService.updateByPrimaryKeySelective(order);

            } else {

                if (groupOrder.getOrderStatus().equals(0)) {

                    groupOrder.setOrderStatus(2);
                    groupOrderMapper.updateByPrimaryKeySelective(groupOrder);

                    //不中者
                    w++;
                    List<Refunds> refunds = orderService.cancel(order.getId(), sn + "-" + String.valueOf(w));
                    refundsList.addAll(0,refunds);

                    //不中者领红包
                    Member member = memberMapper.selectByPrimaryKey(groupOrder.getMemberId());

                    pointService.addPoint(member.getId(), groupBuy.getPoint().setScale(0, BigDecimal.ROUND_HALF_DOWN).longValue(), "参与团购-贡献奖", 0, order.getId());

                }

            }

        }

        //结束原来那期
        GroupPeriod groupPeriod = groupPeriodMapper.selectByPrimaryKey(groupBuy.getPeriodId());
        groupPeriod.setStatus(2);
        groupPeriodMapper.updateByPrimaryKeySelective(groupPeriod);

        //新开一期
        groupPeriod = new GroupPeriod();
        groupPeriod.setBuyNum(0);
        groupPeriod.setGroupBuyId(groupBuy.getId());
        groupPeriod.setGroupNum(groupBuy.getGroupNum());
        groupPeriod.setCreateDate(new Date());
        groupPeriod.setStatus(0);
        groupPeriod.setPeriodNum(groupBuy.getPeriodNum()+1);
        groupPeriodMapper.insertUseGeneratedKeys(groupPeriod);

        //获取上期未生效订单，放入本期内

        Map<String,Object> params = new HashMap<>();
        params.put("periodId",0L);
        params.put("robot",0);
        params.put("groupBuyId",groupBuy.getId());
        Integer buyNum = 0;
        List<GroupOrder> orderList = groupOrderMapper.selectList(params);
        for (GroupOrder order:orderList) {
            if (buyNum<=groupBuy.getGroupNum()) {
                order.setPeriodId(groupPeriod.getId());
                groupOrderMapper.updateByPrimaryKeySelective(order);
                buyNum++;
            }
        }

        groupPeriod.setBuyNum(buyNum);
        groupPeriodMapper.updateByPrimaryKeySelective(groupPeriod);

        groupBuy.setStatus(1);
        groupBuy.setBuyNum(buyNum);
        groupBuy.setPeriodNum(groupBuy.getPeriodNum()+1);
        groupBuy.setPeriodId(groupPeriod.getId());
        groupBuyMapper.updateByPrimaryKeySelective(groupBuy);

        if (groupPeriod.getBuyNum()>=groupBuy.getGroupNum()) {
            groupPeriod.setStatus(1);
            groupBuy.setStatus(2);
            groupBuyMapper.updateByPrimaryKeySelective(groupBuy);

            List<GroupOrder> gOrderList = getOrderList(groupBuy.getPeriodId());

            //开始随机获取中奖者
            Integer g = groupBuy.getOrderNum();
            if (g>gOrderList.size()) {
                g = gOrderList.size();
            }
            List<Integer> rd = new ArrayList<>();
            Random r = new Random();
            while (g>0) {
                if (gOrderList.size()>1) {
                    int n = r.nextInt(gOrderList.size());
                    if (rd.indexOf(n) < 0) {
                        rd.add(n);
                        g--;
                    }
                } else {
                    rd.add(0);
                    g--;
                }

            }

            for (Integer i:rd) {
                GroupOrder go = gOrderList.get(i);
                go.setOrderStatus(1);
                groupOrderMapper.updateByPrimaryKeySelective(go);

            }

        }

        return refundsList;

    }

}
